from rest_framework import serializers

from utils.get_request_info import get_login_location, get_browser, get_request_ip
from user.models import UserInfo, OnlinUser
from django_redis import get_redis_connection
from rest_framework.exceptions import ValidationError
import re
from rest_framework_jwt.settings import api_settings

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['username', 'password', 'code', 'uuid']

    username = serializers.CharField()
    code = serializers.CharField()
    uuid = serializers.CharField()

    # dataScopes = serializers.SerializerMethodField(read_only=True)
    # jobs = serializers.CharField(read_only=True)
    # def get_dataScopes(self, obj):
    #     return []
    # roles = serializers.SerializerMethodField(read_only=True)
    # def get_roles(self, obj):
    #     print(obj)
    #     role_list = []
    #     for i in obj.roles:
    #         role_list.append(i.name)
    #     return role_list
    # user = serializers.SerializerMethodField(read_only=True)
    # def get_user(self, obj):
    #     data = {
    #         'avatarPath': obj.avatar_path,
    #         'createTime': obj.create_time,
    #         'dept': {
    #             'id': obj.dept.pk,
    #             'name': obj.dept.name,
    #         },
    #         'email': obj.email,
    #         'enabled': obj.enabled,
    #         'gender': obj.gender,
    #         'id': obj.pk,
    #     }
    #     return data

    def validate(self, attrs):
        code = attrs.get('code')
        uuid = attrs.get('uuid')
        if not self._get_code(uuid, code):
            raise ValidationError('验证码错误')
        user = self._get_user(attrs)
        token = self._get_token(user)
        self._post_online(user)  # 记录在线登录用户
        self.context['token'] = token
        self.context['user'] = user
        return attrs

    def _post_online(self, user):
        request = self.context.get('request')
        data = {
            'create_by': user.username,
            'address': get_login_location(request),
            'browser': get_browser(request) if get_browser(request) else '未知浏览器',
            'ip': get_request_ip(request) if get_request_ip(request) else '未知ip',
            'key': self._get_token(user),
            'user_id': user.pk
        }
        OnlinUser.objects.create(**data)

    def _get_code(self, uuid, code):
        conn = get_redis_connection('code')
        if code == conn.get(uuid).decode('utf-8'):
            return True
        else:
            return False

    def _get_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'^[1]([3-9])[0-9]{9}$', username):
            user = UserInfo.objects.filter(phone=username).first()
        elif re.match(r'[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$', username):
            user = UserInfo.objects.filter(email=username).first()
        else:
            user = UserInfo.objects.filter(username=username).first()
        if user and user.check_password(password):
            UserInfo.objects.filter(pk=user.pk).update(is_login=True)
            return user
        else:
            raise ValidationError('用户名或密码错误')

    def _get_token(self, user):
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token


class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['dataScopes', 'roles', 'user', ]

    dataScopes = serializers.SerializerMethodField()

    def get_dataScopes(self, obj):
        data_scopes = []
        for role in obj.roles.all():
            data_scopes.append(role.data_scope)
        return data_scopes

    roles = serializers.SerializerMethodField()

    def get_roles(self, obj):
        if '超级管理员' in [role.name for role in obj.roles.all()]:
            return ['admin']
        else:
            permission = []
            for role in obj.roles.all():
                for menu in role.menus.all():
                    permission.append(menu.permission)
            return permission

    user = serializers.SerializerMethodField(read_only=True)

    def get_user(self, obj):
        return {
            'avatarPath': 'http://127.0.0.1:8000/media/' + str(obj.avatar_path),
            'createTime': obj.create_time,
            'dept': {
                'id': obj.dept.pk,
                'name': obj.dept.name
            },
            'email': obj.email,
            'enabled': obj.enabled,
            'gender': obj.gender,
            'id': obj.pk,
            'jobs': [{'id': i.pk, 'name': i.name} for i in obj.job.all()],
            'nickName': obj.nick_name,
            'phone': obj.phone,
            'pwdResetTime': obj.pwd_reset_time,
            'roles': [{'dataScope': i.data_scope, 'id': i.pk, 'level': i.level, 'name': i.name} for i in
                      obj.roles.all()],
            'updateBy': obj.update_by,
            'updateTime': obj.update_time,
            'username': obj.username,
        }


class GetUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['avatarPath', 'createBy', 'createTime', 'dept', 'email', 'enabled',
                  'gender', 'id', 'jobs', 'nickName', 'phone', 'roles', 'updateBy', 'updateTime',
                  'username']

    updateBy = serializers.SerializerMethodField()

    def get_updateBy(self, obj):
        return obj.update_by

    updateTime = serializers.SerializerMethodField()

    def get_updateTime(self, obj):
        return obj.update_time

    avatarPath = serializers.SerializerMethodField()

    def get_avatarPath(self, obj):
        return 'http://127.0.0.1:8000/media/' + str(obj.avatar_path)

    createBy = serializers.SerializerMethodField()

    def get_createBy(self, obj):
        return obj.create_by

    createTime = serializers.SerializerMethodField()

    def get_createTime(self, obj):
        return obj.create_time

    dept = serializers.SerializerMethodField()

    def get_dept(self, obj):
        return {
            'id': obj.dept.pk,
            'name': obj.dept.name
        }

    jobs = serializers.SerializerMethodField()

    def get_jobs(self, obj):
        job_list = []
        for i in obj.job.all():
            job_list.append({
                'id': i.pk,
                'name': i.name
            })
        return job_list

    nickName = serializers.SerializerMethodField()

    def get_nickName(self, obj):
        return obj.nick_name

    roles = serializers.SerializerMethodField()

    def get_roles(self, obj):
        role_list = []
        for i in obj.roles.all():
            role_list.append({
                'id': i.pk,
                'dataScope': i.data_scope,
                'level': i.level,
                'name': i.name
            })
        return role_list
